#ifndef MODEL_DAILY_CALENDAR_RULE_HPP
#define MODEL_DAILY_CALENDAR_RULE_HPP

#include "Model/Calendar.hpp"

namespace Model
{

	/// \brief It applies a recurrent calendar rule, which repeats daily.
	/// \details
	///		It manages the daily rules (as ranges of ShortTime) to specify daily time intervals to be applied. In case a 
	///		daily time interval is ending at the end of the day, and another one starts at the beginning of the day, 
	///		when applying the rule, the two intervals are automatically merged into a single one.
	class MODEL_API DailyCalendarRule: public Calendar::Rule
	{
	public:
		// HHMMSS format
		typedef unsigned ShortTime;

	public:
		/// \sa Calendar::Rule::getPeriods( const Calendar::Time&, const Calendar::Time&, Calendar::PeriodSet&);
		virtual void getPeriods( const Calendar::Time& start, const Calendar::Time& end, Calendar::PeriodSet& out);

		/// \brief It adds a daily period to the rule.
		void mergeDailyPeriod( ShortTime start, ShortTime end);

		/// \brief It calculates the date time using the provided day and the time inside the day.
		static Calendar::Time calculateTime( const Calendar::Date& day, ShortTime time);

		/// \brief It extracts the hours from the short time form.
		static unsigned int calculateHours( ShortTime time);

		/// \brief It extracts the minutes from the short time form.
		static unsigned int calculateMinutes( ShortTime time);
		
		/// \brief It extracts the seconds from the short time form.
		static unsigned int calculateSeconds( ShortTime time);

	private:
		typedef utils::interval_set< ShortTime> DailyRanges;

		DailyRanges dailyRanges_;

	private:
		/// \brief It applies the daily rules for the given day.
		/// \param day the day to apply the rule for.
		/// \param periods the collection of time periods to store the result.
		void mergeDailyPeriodsForOneDay( const Calendar::Date& day, Calendar::PeriodSet& periods);

		/// \brief It applies the daily rule for the given time interval.
		/// \param start the start of the time interval to apply the rules for.
		/// \param end the end of the time inteval to apply the rules for.
		/// \param periods the collection of the resulted time periods.
		void calculatePeriodSet( const Calendar::Time& start, const Calendar::Time& end, Calendar::PeriodSet& periods);
	};

} // namespace Model

#endif // MODEL_DAILY_CALENDAR_RULE_HPP
